<

暗黙的なアニメーション

Flutter の使用方法を学ぶ暗黙的アニメーション コードラボへようこそ 特定のプロパティ セットのアニメーションを簡単に作成できるウィジェット。

このコードラボを最大限に活用するには、以下に関する基本的な知識が必要です。

このコードラボでは次の内容を取り上げます。

  • 使用するAnimatedOpacityフェードイン効果を作成します。
  • 使用するAnimatedContainerサイズ、色、余白の変化をアニメーション化します。
  • 暗黙的アニメーションとその使用テクニックの概要。

このコードラボを完了するのにかかる推定時間: 15 ~ 30 分。

暗黙的アニメーションとは何ですか?

flutterズとはアニメーションライブラリ、 モーションを追加して視覚効果を作成できます UI のウィジェット用。 ライブラリに設定された 1 つのウィジェットがアニメーションを管理します。 これらのウィジェットは総称して次のように呼ばれます。暗黙的なアニメーション、 また暗黙的にアニメーション化されたウィジェット、その名前の由来は、暗黙的にアニメーション化されたウィジェット彼らが実装するクラス。 暗黙的なアニメーションを使用すると、 ターゲット値を設定することでウィジェット プロパティをアニメーション化できます。 目標値が変わるたびに、 ウィジェットは、プロパティを古い値から新しい値にアニメーション化します。 このように、暗黙的なアニメーションは利便性のために制御を犠牲にします。 アニメーション効果を管理する必要がないようにします。

例: フェードインテキスト効果

次の例は、既存の UI にフェードイン効果を追加する方法を示しています。 という暗黙的にアニメーション化されたウィジェットを使用します。アニメーションの不透明度。この例はアニメーション コードなしで始まります-それ で構成されています素材アプリホーム画面には以下が含まれます:

  • フクロウの写真。
  • 詳細を表示クリックしても何もしないボタン。
  • 写真内のフクロウの説明文。

フェードイン(スターターコード)

クリック走るボタンをクリックして例を実行します。

{$ begin main.dart $}
import 'package:flutter/material.dart';

const owlUrl =
    'https://raw.githubusercontent.com/flutter/website/main/src/assets/images/docs/owl.jpg';

class FadeInDemo extends StatefulWidget {
  const FadeInDemo({Key? key}) : super(key: key);

  @override
  State<FadeInDemo> createState() => _FadeInDemoState();
}

class _FadeInDemoState extends State<FadeInDemo> {
  @override
  Widget build(BuildContext context) {
    return Column(children: <Widget>[
      Image.network(owlUrl),
      TextButton(
          child: const Text(
            'Show Details',
            style: TextStyle(color: Colors.blueAccent),
          ),
          onPressed: () => {}),
    const Column(
        children: [
          Text('Type: Owl'),
          Text('Age: 39'),
          Text('Employment: None'),
        ],
      )
    ]);
  }
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: Scaffold(
        body: Center(
          child: FadeInDemo(),
        ),
      ),
    );
  }
}

void main() {
  runApp(
    const MyApp(),
  );
}
{$ end main.dart $}

AnimatedOpacity ウィジェットを使用して不透明度をアニメーション化する

このセクションには、 暗黙的なアニメーションフェードインスターターコード。手順の後に、次のコマンドを実行することもできます。フェードイン完了すでに変更が加えられたコード。 手順は、AnimatedOpacityウィジェットを使用して、次のアニメーション機能を追加します。

  • フクロウの説明テキストは、ユーザーがクリックするまで非表示のままです。詳細を表示ボタン。
  • ユーザーがクリックすると、詳細を表示ボタン、 フクロウの説明テキストがフェードインします。

1. アニメーション化するウィジェットのプロパティを選択します

フェードイン効果を作成するには、opacityを使用したプロパティAnimatedOpacityウィジェット。変更ColumnウィジェットへのAnimatedOpacityウィジェット:

{不透明度1 → 不透明度2}/lib/main.dart
@@ -2,6 +2,8 @@
2
2
  // このソース コードの使用は BSD スタイルのライセンスによって管理されます
3
3
  // これは LICENSE ファイルにあります。
4
+ // ファイルの無視: missing_required_argument
5
+
4
6
  import 'パッケージ:flutter/material.dart';
5
7
  const owlUrl =
@@ -25,12 +27,14 @@
25
27
  スタイル: TextStyle(色: Colors.blueAccent)、
26
28
  )、
27
29
  onPressed: () => {})、
28
- 定数列(
29
- 子供:[
30
- テキストタイプ:フクロウ')、
31
- 文章(':39')、
32
- 文章('雇用:なし')、
33
-
30
+ アニメーションの不透明度(
31
+ 子供:const 列(
32
+ 子供:[
33
+ 文章('タイプ:フクロウ')、
34
+ 文章(':39')、
35
+ Text('雇用:なし')
36
+ ]、
37
+ )、
34
38
  )
35
39
  ]);
36
40
  }

2. アニメーション化されたプロパティの状態変数を初期化します。

ユーザーがクリックする前にテキストを非表示にするには詳細を表示、 設定 の開始値opacityゼロに:

{opacity2 → opacity3}/lib/main.dart
@@ -2,8 +2,6 @@
2
2
  // このソース コードの使用は BSD スタイルのライセンスによって管理されます
3
3
  // これは LICENSE ファイルにあります。
4
- // ファイルの無視: missing_required_argument
5
-
6
4
  import 'パッケージ:flutter/material.dart';
7
5
  const owlUrl =
@@ -17,6 +15,8 @@
17
15
  }
18
16
  class _FadeInDemoState extends State<FadeInDemo> {
17
+ 倍の不透明度 = 0.0;
18
+
19
19
  @オーバーライド
20
20
  ウィジェットのビルド(BuildContext context) {
21
21
  return Column(children: <ウィジェット>[
@@ -28,6 +28,8 @@
28
28
  )、
29
29
  onPressed: () => {})、
30
30
  AnimatedOpacity(
31
+ 期間: const 期間(秒: 3)、
32
+ 不透明度: 不透明度、
31
33
  子: const Column(
32
34
  子供: [
33
35
  Text('タイプ: フクロウ'),

3. アニメーションの長さを設定します

に加えて、opacityパラメータ、AnimatedOpacityが必要です間隔アニメーションに使用します。この例では、 2 秒から始めることができます。

{opacity3 → opacity4}/lib/main.dart
@@ -28,7 +28,7 @@
28
28
  )、
29
29
  onPressed: () => {})、
30
30
  AnimatedOpacity(
31
- 期間: const 期間(秒:3)、
31
+ 期間: const 期間(秒:2)、
32
32
  不透明度: 不透明度、
33
33
  子: const Column(
34
34
  子供: [

4. アニメーションのトリガーを設定し、終了値を選択します

ユーザーがクリックしたときにトリガーされるアニメーションを構成します。詳細を表示ボタン。これを行うには、変更しますopacityを使用した状態onPressed()のハンドラーTextButton。を作るには、FadeInDemoウィジェットが完全に表示されるようになった場合 ユーザーがクリックすると、詳細を表示ボタンを使用してくださいonPressed()ハンドラ 設定するopacity1に:

{opacity4 → opacity5}/lib/main.dart
@@ -22,11 +22,14 @@
22
22
  return Column(children: <ウィジェット>[
23
23
  画像.ネットワーク(owlUrl)、
24
24
  テキストボタン(
25
- 子: const Text(
26
- '詳細を表示'、
27
- スタイル: TextStyle(色: Colors.blueAccent)、
28
- )、
29
- onPressed: () => {})、
25
+ 子: const Text(
26
+ '詳細を表示'、
27
+ スタイル: TextStyle(色: Colors.blueAccent)、
28
+ )、
29
+ onPressed: () =>setState((){
30
+ 不透明度 = 1;
31
+ })、
32
+ )、
30
33
  AnimatedOpacity(
31
34
  期間: const 期間(秒: 2)、
32
35
  不透明度: 不透明度、

フェードイン(完了)

完了した変更を含む例を次に示します。これを実行します。 例を選択し、詳細を表示アニメーションをトリガーするボタン。

{$ begin main.dart $}
import 'package:flutter/material.dart';

const owlUrl =
    'https://raw.githubusercontent.com/flutter/website/main/src/assets/images/docs/owl.jpg';

class FadeInDemo extends StatefulWidget {
  const FadeInDemo({Key? key}) : super(key: key);

  @override
  State<FadeInDemo> createState() => _FadeInDemoState();
}

class _FadeInDemoState extends State<FadeInDemo> {
  double opacity = 0.0;

  @override
  Widget build(BuildContext context) {
    return Column(children: <Widget>[
      Image.network(owlUrl),
      TextButton(
        child: const Text(
          'Show Details',
          style: TextStyle(color: Colors.blueAccent),
        ),
        onPressed: () => setState(() {
          opacity = 1;
        }),
      ),
      AnimatedOpacity(
        duration: const Duration(seconds: 2),
        opacity: opacity,
        child: const Column(
          children: [
            Text('Type: Owl'),
            Text('Age: 39'),
            Text('Employment: None'),
          ],
        ),
      )
    ]);
  }
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: Scaffold(
        body: Center(
          child: FadeInDemo(),
        ),
      ),
    );
  }
}

void main() {
  runApp(
    const MyApp(),
  );
}
{$ end main.dart $}

すべてを一緒に入れて

フェードインテキスト効果この例では、次の機能を示します のAnimatedOpacity:

  • AnimatedOpacity状態の変化をリッスンしますopacity財産。
  • いつでもopacity変化、AnimatedOpacity自動的にアニメーション化します ウィジェットの新しい値への移行opacity
  • AnimatedOpacityが必要ですduration所要時間を定義するパラメータ 古いものから古いものへの移行をアニメーション化するopacity価値と新しいもの。

例: シェイプシフトエフェクト

次の例は、アニメーションコンテナウィジェットへ 複数のプロパティをアニメーション化する (marginborderRadius、 とcolor) と 他の種類 (doubleColor)。この例はアニメーション コードなしで始まります—それはで始まります素材アプリ以下を含むホーム画面:

  • ContainerborderRadiusmargin、 とcolorであるプロパティ 例を実行するたびに異なります。
  • 変化クリックしても何もしないボタン。

シェイプシフト(スターターコード)

クリック走るボタンをクリックして例を実行します。

{$ begin main.dart $}
import 'dart:math';

import 'package:flutter/material.dart';

double randomBorderRadius() {
  return Random().nextDouble() * 64;
}

double randomMargin() {
  return Random().nextDouble() * 64;
}

Color randomColor() {
  return Color(0xFFFFFFFF & Random().nextInt(0xFFFFFFFF));
}

class AnimatedContainerDemo extends StatefulWidget {
  const AnimatedContainerDemo({Key? key}) : super(key: key);

  @override
  State<AnimatedContainerDemo> createState() => _AnimatedContainerDemoState();
}

class _AnimatedContainerDemoState extends State<AnimatedContainerDemo> {
  late Color color;
  late double borderRadius;
  late double margin;

  @override
  initState() {
    super.initState();
    color = randomColor();
    borderRadius = randomBorderRadius();
    margin = randomMargin();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          children: <Widget>[
            SizedBox(
              width: 128,
              height: 128,
              child: Container(
                margin: EdgeInsets.all(margin),
                decoration: BoxDecoration(
                  color: color,
                  borderRadius: BorderRadius.circular(borderRadius),
                ),
              ),
            ),
            ElevatedButton(
              child: const Text('change'),
              onPressed: () => {},
            ),
          ],
        ),
      ),
    );
  }
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: AnimatedContainerDemo(),
    );
  }
}

void main() {
  runApp(
    const MyApp(),
  );
}
{$ end main.dart $}

AnimatedContainer を使用して color、borderRadius、margin をアニメーション化する

このセクションには、 暗黙的なアニメーションシェイプシフトスターターコード。 手順の後に、次のコマンドを実行することもできます。シェイプシフト完了すでに変更が加えられている例。

の中にシェイプシフトスターターコード、 の各プロパティContainerウィジェット (colorborderRadius、 とmargin) 関連する関数 (randomColor()randomBorderRadius()、 とrandomMargin()それぞれ)。 を使用することで、AnimatedContainerウィジェット、 このコードをリファクタリングして次のことを行うことができます。

  • 新しい値を生成するcolorborderRadius、 とmarginユーザーがクリックするたびに、変化ボタン。
  • 新しい値への移行をアニメーション化するcolorborderRadius、 とmargin設定されるたびに。

1. 暗黙的なアニメーションを追加する

変更ContainerウィジェットへのAnimatedContainerウィジェット:

{コンテナ1 → コンテナ2}/lib/main.dart
@@ -2,6 +2,8 @@
2
2
  // このソース コードの使用は BSD スタイルのライセンスによって管理されます
3
3
  // これは LICENSE ファイルにあります。
4
+ // ファイルの無視: missing_required_argument
5
+
4
6
  インポート 'dart:math';
5
7
  import 'パッケージ:flutter/material.dart';
@@ -47,7 +49,7 @@
47
49
  SizedBox(
48
50
  幅: 128、
49
51
  身長: 128、
50
- 子供:容器(
52
+ 子供:アニメーションコンテナ(
51
53
  マージン: EdgeInsets.all(マージン)、
52
54
  装飾: BoxDecoration(
53
55
  色: 色、

2. アニメーション化されたプロパティの開始値を設定する

AnimatedContainerの古い値と新しい値の間で自動的にアニメーションが表示されます。 変更されたときのそのプロパティ。を作成しますchange()を定義するメソッド ユーザーがクリックしたときにトリガーされる動作変化ボタン。 のchange()使用できるメソッドsetState()新しい値を設定する のためにcolorborderRadius、 とmargin状態変数:

{コンテナ2 → コンテナ3}/lib/main.dart
@@ -40,6 +40,14 @@
40
40
  マージン = ランダムマージン();
41
41
  }
42
+ void change() {
43
+ setState(() {
44
+ カラー = ランダムカラー();
45
+ borderRadius = ランダムBorderRadius();
46
+ マージン = ランダムマージン();
47
+ });
48
+ }
49
+
42
50
  @オーバーライド
43
51
  ウィジェットのビルド(BuildContext context) {
44
52
  足場を返す(

3. アニメーションのトリガーを設定する

ユーザーがボタンを押すたびにアニメーションがトリガーされるように設定するには、変化ボタン、 を呼び出すchange()のメソッドonPressed()ハンドラ:

{コンテナ3 → コンテナ4}/lib/main.dart
@@ -67,7 +67,7 @@
67
67
  )、
68
68
  エレベーテッドボタン(
69
69
  子: const Text('change')、
70
- onPressed: () =>{}
70
+ onPressed: () =>変化()
71
71
  )、
72
72
  ]、
73
73
  )、

4. 持続時間を設定する

最後に、durationトランジションを強化するアニメーションの 古い値と新しい値の間:

{コンテナ4 → コンテナ5}/lib/main.dart
@@ -2,12 +2,12 @@
2
2
  // このソース コードの使用は BSD スタイルのライセンスによって管理されます
3
3
  // これは LICENSE ファイルにあります。
4
- // ファイルの無視: missing_required_argument
5
-
6
4
  インポート 'dart:math';
7
5
  import 'パッケージ:flutter/material.dart';
6
+ const _duration = 期間(ミリ秒: 400);
7
+
8
8
  ダブルランダムBorderRadius() {
9
9
  ランダム().nextDouble() * 64を返します。
10
10
  }
@@ -63,6 +63,7 @@
63
63
  色: 色、
64
64
  borderRadius: BorderRadius.circular(borderRadius),
65
65
  )、
66
+ 期間: _期間、
66
67
  )、
67
68
  )、
68
69
  エレベーテッドボタン(

シェイプシフト(完了)

完了した変更を含む例を次に示します。コードを実行します。 そして、変化アニメーションをトリガーするボタン。毎回注意してください をクリックすると変化ボタンをクリックすると、形状が新しい値にアニメーション化されます。 ためにmarginborderRadius、 とcolor

{$ begin main.dart $}
import 'dart:math';

import 'package:flutter/material.dart';

const _duration = Duration(milliseconds: 400);

double randomBorderRadius() {
  return Random().nextDouble() * 64;
}

double randomMargin() {
  return Random().nextDouble() * 64;
}

Color randomColor() {
  return Color(0xFFFFFFFF & Random().nextInt(0xFFFFFFFF));
}

class AnimatedContainerDemo extends StatefulWidget {
  const AnimatedContainerDemo({Key? key}) : super(key: key);

  @override
  State<AnimatedContainerDemo> createState() => _AnimatedContainerDemoState();
}

class _AnimatedContainerDemoState extends State<AnimatedContainerDemo> {
  late Color color;
  late double borderRadius;
  late double margin;

  @override
  initState() {
    super.initState();
    color = randomColor();
    borderRadius = randomBorderRadius();
    margin = randomMargin();
  }

  void change() {
    setState(() {
      color = randomColor();
      borderRadius = randomBorderRadius();
      margin = randomMargin();
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          children: <Widget>[
            SizedBox(
              width: 128,
              height: 128,
              child: AnimatedContainer(
                margin: EdgeInsets.all(margin),
                decoration: BoxDecoration(
                  color: color,
                  borderRadius: BorderRadius.circular(borderRadius),
                ),
                duration: _duration,
              ),
            ),
            ElevatedButton(
              child: const Text('change'),
              onPressed: () => change(),
            ),
          ],
        ),
      ),
    );
  }
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: AnimatedContainerDemo(),
    );
  }
}

void main() {
  runApp(
    const MyApp(),
  );
}
{$ end main.dart $}

アニメーションカーブの使用

前述の例は、暗黙的なアニメーションによってどのようにアニメーション化できるかを示しています。 特定のウィジェットのプロパティの値の変更と、durationパラメータを使用すると、 アニメーションが完了するまでに時間がかかります。暗黙的なアニメーションを使用すると、次のことも可能になります。 コントロールの変更をレート内のアニメーションのduration。 この速度の変化を定義するために使用するパラメータは次のとおりです。曲線。

前述の例では、curve、 したがって、暗黙的なアニメーションは線形アニメーション曲線デフォルトでは。 追加curveパラメータへのシェイプシフト完了を通過したときにアニメーションがどのように変化するかを見てください。イーズインアウトバック定数curve:

{コンテナ5 → コンテナ6}/lib/main.dart
@@ -64,6 +64,7 @@
64
64
  borderRadius: BorderRadius.circular(borderRadius),
65
65
  )、
66
66
  期間: _期間、
67
+ カーブ: Curves.easeInOutBack、
67
68
  )、
68
69
  )、
69
70
  エレベーテッドボタン(

あなたが過ぎた今、easeInOutBackの値としてcurveAnimatedContainerの変化率に注目してください。marginborderRadius、 とcolorで定義された曲線に従います。easeInOutBack曲線:

すべてを一緒に入れて

シェイプシフト完了例では、次の値の間の遷移をアニメーション化します。marginborderRadius、 とcolorプロパティ。 ご了承くださいAnimatedContainerプロパティのいずれかの変更をアニメーション化します。 使用しなかったものも含めて、paddingtransform、 そしてさらにchildalignment! のシェイプシフト完了例はそれに基づいて構築されますフェードイン完了見せることで 暗黙的アニメーションの追加機能:

  • いくつかの暗黙的なアニメーション (例:AnimatedOpacity) 1 つのみをアニメーション化します プロパティ、一方で他のもの(AnimatedContainer) 多くのプロパティをアニメーション化できます。
  • 暗黙的なアニメーションは、古いアニメーションと古いアニメーションの間で自動的にアニメーション化されます。 提供されたプロパティを使用して変更されたときのプロパティの新しい値curveduration
  • を指定しない場合は、curve、 暗黙的なアニメーションのデフォルトは直線的な曲線。

次は何ですか?

おめでとうございます。コードラボは完了しました。さらに詳しく知りたい場合は、 次にどこに進むべきかについて、いくつかの提案を示します。